﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MotoreDataBase;

namespace TestProject
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class UnitTest1
    {
        public UnitTest1()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestInitialize]
        public void Initialize()
        {
            CreateDataBase.stringConnection = "data source=.\\SQLEXPRESS;Integrated Security=True;initial catalog=ProvaDb";
            
            bool exist = CreateDataBase.TableExist<ClasseDiTest>();

            if(exist)
            {
                CreateDataBase.DeleteTable<ClasseDiTest>();
                Assert.AreEqual(false, CreateDataBase.TableExist<ClasseDiTest>());
            }
            CreateDataBase.CreaTabella<ClasseDiTest>();
            Assert.AreEqual(true, CreateDataBase.TableExist<ClasseDiTest>());
           
        }

        [TestMethod]
        public void TestMethodGetList()
        {
            GestoreBase.stringConnection = "data source=.\\SQLEXPRESS;Integrated Security=True;initial catalog=ProvaDb";
            List<ClasseDiTest> lista = new List<ClasseDiTest>();
            lista.Add(new ClasseDiTest { Nome = "Nome3", Cognome = "Cognome3", DataNow = DateTime.Now, EnumTest = EnumTest.val1 });
            lista.Add(new ClasseDiTest { Nome = "Nome2", Cognome = "Cognome2", DataNow = DateTime.Now, EnumTest = EnumTest.val2});
            foreach (var item in lista)
            {
                GestoreBase.Insert<ClasseDiTest>(item);
            }
            List<ClasseDiTest> output = GestoreBase.GetList<ClasseDiTest>();
            for (int i = 0; i < output.Count; i++)
            {
                Assert.AreEqual(lista[i], output[i]);
            }
        }


        [TestMethod]
        public void TestPersonalQuery()
        {
            GestoreBase.stringConnection = "data source=.\\SQLEXPRESS;Integrated Security=True;initial catalog=ProvaDb";
            ClasseDiTest item = new ClasseDiTest { Nome = "Nome1", Cognome = "Cognome1", DataNow = DateTime.Now };
            GestoreBase.Insert<ClasseDiTest>(item);
            ClasseDiTest returnValue = GestoreBase.ExecuteNonQueryToObject<ClasseDiTest>("SelectForId", new Parameter("Id",1));
            Assert.AreEqual(1, returnValue.Id);
        }

        [TestMethod]
        public void TestInsertWithId()
        {
            GestoreBase.stringConnection = "data source=.\\SQLEXPRESS;Integrated Security=True;initial catalog=ProvaDb";
            ClasseDiTest item = new ClasseDiTest { Nome = "NomeId", Cognome = "CognomeId", DataNow = DateTime.Now };
            GestoreBase.Insert<ClasseDiTest>(item);
            item = GestoreBase.InsertWithId<ClasseDiTest>(item);
            ClasseDiTest returnValue = GestoreBase.ExecuteNonQueryToObject<ClasseDiTest>("SelectNC", new Parameter("Cognome", item.Cognome), new Parameter("Nome",item.Nome));
            Assert.AreEqual(item.Id, returnValue.Id);
        }

        [TestMethod]
        public void TestSelectWithProp()
        {
            GestoreBase.stringConnection = "data source=.\\SQLEXPRESS;Integrated Security=True;initial catalog=ProvaDb";
            ClasseDiTest item = new ClasseDiTest { Nome = "NomeId", Cognome = "CognomeId", DataNow = DateTime.Now };
            GestoreBase.Insert<ClasseDiTest>(item);
            List<ClasseDiTest> lista = GestoreBase.GetList<ClasseDiTest>(typeof(ClasseDiTest).GetProperty("Nome"), typeof(ClasseDiTest).GetProperty("Cognome"));
            Assert.AreEqual(item.Nome, lista[0].Nome);

        }

        [TestMethod]
        public void TestGetGenericList()
        {
            GestoreBase.stringConnection = "data source=.\\SQLEXPRESS;Integrated Security=True;initial catalog=ProvaDb";
            ClasseDiTest item = new ClasseDiTest { Nome = "NomeId", Cognome = "CognomeId", DataNow = DateTime.Now };
            GestoreBase.Insert<ClasseDiTest>(item);
            List<string> lista = MotoreDataBase.GestoreBase.ExecuteNonQueryToListOfString<ClasseDiTest>("SelectN", null);
            Assert.AreEqual(lista[0], item.Nome); 
           
        }

    }

    [Nome("ClassiTest")]
    [NonQuery("SelectForId", "SELECT * FROM ClassiTest WHERE Id = @Id")]
    [NonQuery("SelectNC", "SELECT * FROM ClassiTest WHERE Nome = @Nome AND Cognome = @Cognome")]
    [NonQuery("SelectN", "SELECT Nome FROM ClassiTest")]
    [NonQuery("SelectId", "SELECT Id FROM ClassiTest")]

    public class ClasseDiTest
    {
        [Nome("Id")]
        [TableDefinition(TipoDatiDb.INT,0,false,true,true)]
        public int Id { get; set; }

        [Nome("Nome")]
        [TableDefinition(TipoDatiDb.VARCHAR, 100)]
        public string Nome { get; set; }

        [Nome("Cognome")]
        [TableDefinition(TipoDatiDb.VARCHAR, 100)]
        public string Cognome { get; set; }
        
        [Nome("Data")]
        [TableDefinition(TipoDatiDb.DATETIME)]
        public DateTime DataNow { get; set; }

        [Nome("EnumTest")]
        [TableDefinition(TipoDatiDb.VARCHAR, 100)]
        public EnumTest EnumTest { get; set; }

        public override bool Equals(object obj)
        {
            ClasseDiTest temp = (ClasseDiTest)obj;
            return (this.Nome.Equals(temp.Nome) && this.Cognome.Equals(temp.Cognome) && this.DataNow.ToString().Equals(temp.DataNow.ToString()));
        }
    }

    public enum EnumTest
    {
        val1,
        val2,
        val3
    }

    public class ListClasseTest : List<ClasseDiTest>
    { }
}
